﻿using adb群控.model;
using adb群控.util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace adb群控.service
{
    class Service
    {

        /// <summary>
        /// 获取全部设备信息
        /// </summary>
        /// <returns></returns>
        public List<model.Device> getAllDevice()
        {
            try
            {
                List<model.Device> list = new List<model.Device>();
                //执行adb device命令获取全部信息
                String cmdDevice = "host:devices";
                CmdUtil cmdUtil = new CmdUtil();
                String devicesStr = this.sendMessageToAdbRec(cmdDevice);
                devicesStr = devicesStr.Substring(8);
                //换行符号分隔去掉头部信息
                String[] deviceListStr = devicesStr.Split(new string[] { "\n" }, StringSplitOptions.None);
                //在index 5 开始去
                int port = 1717;
                for (int i = 0; i < deviceListStr.Length - 1; i++)
                {
                    model.Device devvice = new model.Device();
                    String[] deviceNames = deviceListStr[i].Split(new string[] { "\t" }, StringSplitOptions.None);
                    devvice.Name = deviceNames[0];
                    devvice.Status = deviceNames[1];
                    //获取cpu版本信息
                    String cpuCmd1 = String.Format("host:transport:{0}", devvice.Name);
                    String cpuCmd2 = String.Format("shell:command getprop ro.product.cpu.abi");
                    String cpuMessageStr = this.sendMessageToAdbRec(cpuCmd1, cpuCmd2);
                    String[] cpuMessage = cpuMessageStr.Split(new string[] { "\r" }, StringSplitOptions.None);
                    devvice.CupAbi = cpuMessage[0];
                    //获取sdk版本
                    String sdkVersionCmd = "shell:command getprop ro.build.version.sdk";
                    String sdkVersionStr = this.sendMessageToAdbRec(cpuCmd1, sdkVersionCmd);
                    String[] sdkVersion = sdkVersionStr.Split(new string[] { "\r" }, StringSplitOptions.None);

                    devvice.SdkVersion = sdkVersion[0];
                    //获取系统分辨率
                    String vmsizeCmd = "shell:command wm size";
                    String[] svmsizeCmdStr = this.sendMessageToAdbRec(cpuCmd1, vmsizeCmd).Split(new string[] { "\r" }, StringSplitOptions.None);
                    String xy = null;

                    if (svmsizeCmdStr[0].Split(new string[] { ":" }, StringSplitOptions.None).Length >= 2)
                    {
                        xy = svmsizeCmdStr[0].Split(new string[] { ":" }, StringSplitOptions.None)[1];
                    }


                    if (xy != null)
                    {
                        devvice.Higth = xy.Split(new string[] { "x" }, StringSplitOptions.None)[0];
                        devvice.Width = xy.Split(new string[] { "x" }, StringSplitOptions.None)[1];
                    }
                    devvice.Port = port;
                    port = port + 1;
                    //获取preSDK 信息
                    list.Add(devvice);
                }
                return list;
            }
            catch (Exception e)
            {
                Debug.WriteLine("获取设备信息列表错误：" + e.Message);
                return null;

            }

        }



        /// <summary>
        ///初始化设备
        /// </summary>
        /// <returns></returns>
        public String initDevices(model.Device device)
        {
            try
            {
                CmdUtil cmd = new CmdUtil();
                String dir = "/data/local/tmp";
                String cmdHeader = "adb -s  " + device.Name + " ";
                //创建目录
                cmd.excute(String.Format(cmdHeader + " shell \"mkdir " + dir + " 2>/dev/null || true\""));
                //上传文件
                String soPath = String.Format(CommonValue.LIBS_SO_FILE_PATH + "\\aosp\\libs\\android-{0}\\{1}\\minicap.so", device.SdkVersion, device.CupAbi);
                cmd.excute(String.Format(cmdHeader + " push {0}   {1}", soPath, dir));
                //需要判断sdk版打印16的使用minicap文件否则minicap-nopie
                if (Convert.ToInt32(device.SdkVersion) >= 16)
                {
                    String minicopFile = String.Format(CommonValue.LIBS_SO_FILE_PATH + "\\libs\\{0}\\minicap", device.CupAbi);
                    cmd.excute(String.Format(cmdHeader + " push {0}   {1}", minicopFile, dir));
                }
                else
                {
                    String minicopFile = String.Format(CommonValue.LIBS_SO_FILE_PATH + "\\libs\\{0}\\minicap-nopie", device.CupAbi);
                    cmd.excute(String.Format(cmdHeader + " push {0}   {1}", minicopFile, dir));
                }
                //授权777
                cmd.excute(String.Format(cmdHeader + " shell  chmod -R  777 " + dir));
                return "success";
            }

            catch (Exception e)
            {
                Debug.WriteLine("初始设备失败：" + e.Message);
                return "false";
            }

        }

        /// <summary>
        /// 重启设备
        /// </summary>
        /// <param name="deviceName">设备名称</param>
        public void deviceReBoot(String deviceName)
        {
            CmdUtil cmd = new CmdUtil();

            String cmdStr = String.Format("adb -s {0} reboot", deviceName);
            cmd.excute(cmdStr);
        }

        /// <summary>
        /// 关闭进程
        /// </summary>
        public void closeProcess()
        {
            Process[] pro = Process.GetProcesses();//获取已开启的所有进程
            //遍历所有查找到的进程
            for (int i = 0; i < pro.Length; i++)
            {
                //Debug.WriteLine("==============" + pro[i].ProcessName + "================");
                //判断此进程是否是要查找的进程
                if (pro[i].ProcessName.ToString().ToLower().Contains("adb") || pro[i].ProcessName.ToString().ToLower().Contains("cmd")
                    || pro[i].ProcessName.ToString().ToLower().Contains("conhost"))
                {
                    try
                    {
                        Debug.WriteLine(pro[i].ProcessName);
                        pro[i].Kill();//结束进程
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("关闭adb进程出错!" + ex.Message);
                    }

                }
            }
        }

        /// <summary>
        /// 发送消息到adb需要接收返回
        /// </summary>
        /// <param name="msg">发送信息</param>
        /// <returns>返回信息</returns>
        public String sendMessageToAdbRec(String msg)
        {
            msg = getMessageAddLength(msg);
            //设定服务器IP地址  
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 5037)); //配置服务器IP与端口  
                Debug.WriteLine("连接服务器成功");
            }
            catch
            {
                Debug.WriteLine("连接服务器失败，请按回车键退出！");
                return "";
            }

            // string sendMessage = "你好";//发送到服务端的内容
            clientSocket.Send(Encoding.UTF8.GetBytes(msg));//向服务器发送数据，需要发送中文则需要使用Encoding.UTF8.GetBytes()，否则会乱码
            Debug.WriteLine("向服务器发送消息：" + msg);

            //接受从服务器返回的信息
            string recvStr = "";
            byte[] recvBytes = new byte[1024];
            int bytes;
            bytes = clientSocket.Receive(recvBytes, recvBytes.Length, 0);    //从服务器端接受返回信息 
            recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
            Debug.WriteLine("服务端发来消息：" + recvStr);//回显服务器的返回信息
            //每次完成通信后，关闭连接并释放资源
            clientSocket.Close();
            return recvStr;
        }


        /// <summary>
        /// 发送信息到abd不需要接收返回
        /// </summary>
        /// <param name="msg">信息报文</param>

        public void sendMessageToAdbNotRec(String msg)
        {
            //设定服务器IP地址  
            msg = getMessageAddLength(msg);
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 5037)); //配置服务器IP与端口  
                Debug.WriteLine("连接服务器成功");
            }
            catch
            {
                Debug.WriteLine("连接服务器失败，请按回车键退出！");
            }

            // string sendMessage = "你好";//发送到服务端的内容
            clientSocket.Send(Encoding.UTF8.GetBytes(msg));//向服务器发送数据，需要发送中文则需要使用Encoding.UTF8.GetBytes()，否则会乱码
            Console.WriteLine("向服务器发送消息：" + msg);
            //每次完成通信后，关闭连接并释放资源
            clientSocket.Close();
        }

        public string getMessageAddLength(string message)
        {
            int length = message.Length;
            //将长度转16进制
            string strLength16 = length.ToString("x4");
            String cmd = strLength16 + message;
            return cmd;
        }

        /// <summary>
        /// 联系发送两条命令
        /// </summary>
        /// <param name="cmd1">命令1</param>
        /// <param name="cmd2">命令2</param>
        /// <returns></returns>
        public String sendMessageToAdbRec(String cmd1, String cmd2)
        {
            cmd1 = getMessageAddLength(cmd1);
            cmd2 = getMessageAddLength(cmd2);
            //设定服务器IP地址  
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 5037)); //配置服务器IP与端口  
                Debug.WriteLine("连接服务器成功");
            }
            catch
            {
                Debug.WriteLine("连接服务器失败，请按回车键退出！");
                return "";
            }

            // string sendMessage = "你好";//发送到服务端的内容
            clientSocket.Send(Encoding.UTF8.GetBytes(cmd1));//向服务器发送数据，需要发送中文则需要使用Encoding.UTF8.GetBytes()，否则会乱码
            Debug.WriteLine("向服务器发送消息：" + cmd1);

            //接受从服务器返回的信息
            string recvStr = "";
            byte[] recvBytes = new byte[1024];
            int bytes;
            bytes = clientSocket.Receive(recvBytes, recvBytes.Length, 0);    //从服务器端接受返回信息 
            recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
            Debug.WriteLine("服务端发来消息：" + recvStr);//回显服务器的返回信息
            //每次完成通信后，关闭连接并释放资源
            clientSocket.Send(Encoding.UTF8.GetBytes(cmd2));
            Debug.WriteLine("向服务器发送消息：" + cmd2);
            //接受从服务器返回的信息
            string recvStr1 = "";
            byte[] recvBytes1 = new byte[1024];
            int bytes1;
            bytes1 = clientSocket.Receive(recvBytes1, recvBytes1.Length, 0);    //从服务器端接受返回信息 
            recvStr1 += Encoding.UTF8.GetString(recvBytes1, 0, bytes1);
            int bytes2;
            string recvStr2 = "";
            byte[] recvBytes2 = new byte[1024];
            bytes2 = clientSocket.Receive(recvBytes2, recvBytes2.Length, 0);    //从服务器端接受返回信息 
            recvStr2 += Encoding.UTF8.GetString(recvBytes2, 0, bytes2);



            clientSocket.Close();
            Debug.WriteLine("向服务器发送消息：" + recvStr2);
            return recvStr2;
        }


        /// <summary>
        /// 联系发送两条命令
        /// </summary>
        /// <param name="cmd1">命令1</param>
        /// <param name="cmd2">命令2</param>
        /// <returns></returns>
        public void sendMessageToAdbNotRec(String cmd1, String cmd2)
        {
            cmd1 = getMessageAddLength(cmd1);
            cmd2 = getMessageAddLength(cmd2);
            //设定服务器IP地址  
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 5037)); //配置服务器IP与端口  
                Debug.WriteLine("连接服务器成功");
            }
            catch
            {
                Debug.WriteLine("连接服务器失败，请按回车键退出！");
               
            }

            // string sendMessage = "你好";//发送到服务端的内容
            clientSocket.Send(Encoding.UTF8.GetBytes(cmd1));//向服务器发送数据，需要发送中文则需要使用Encoding.UTF8.GetBytes()，否则会乱码
            Debug.WriteLine("向服务器发送消息：" + cmd1);

            //每次完成通信后，关闭连接并释放资源
            clientSocket.Send(Encoding.UTF8.GetBytes(cmd2));
            Debug.WriteLine("向服务器发送消息：" + cmd2);
        }
    }
}
